<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>帧动画</title>
  <style>
    body {
      margin: 0;
      overflow: hidden;
      /* 隐藏body窗口区域滚动条 */
    }
  </style>
  <!--引入three.js三维引擎-->
  <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js"></script>
  <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/controls/OrbitControls.js"></script>
  <!-- <script src="./three.js"></script> -->
  <!-- <script src="http://www.yanhuangxueyuan.com/threejs/build/three.js"></script> -->
</head>

<body>
  <input type="range" name="slider" min="1" max="100" step="1" value="0" style="position: absolute; top: 10px;left: 10px;"/>
  <script src="static/js/main.js"></script>
  <script>
    /**
     * 创建场景对象Scene
     */
    let scene = new THREE.Scene();
    
    let group = new THREE.Group()
    mesh = genMesh({
        geometry: new THREE.SphereGeometry(100, 40, 20),
        material: new THREE.MeshPhongMaterial({
            side: THREE.DoubleSide, //两面可见
            color: 0x446688,
        })
    })
    // 网格模型命名,KeyframeTrack引用
    mesh.name = 'Sphere'
    group.add(mesh)
    mesh = genMesh({
        geometry: new THREE.BoxGeometry(100, 100, 100),
        material: new THREE.MeshPhongMaterial({
            side: THREE.DoubleSide, //两面可见
            color: 0xff00ff,
        })
    })
    // 网格模型命名,KeyframeTrack引用
    mesh.name = 'Box'
    group.add(mesh); 
    
    scene.add(group)
    // 创建名为Box对象的位置关键帧,每个时间节点对应一组位置
    let posTrack = new THREE.KeyframeTrack('Box.position', [0, 10, 20], [0, 0, 0, 500, 0, 0, 0, 0, 0])
    // let posTrack = new THREE.KeyframeTrack('Box.position', [0, 20], [0, 0, 0, 150, 0, 0])
    // 创建名为Box对象的颜色关键帧,每个时间节点对应一组颜色值
    let colorKF = new THREE.KeyframeTrack('Box.material.color', [10, 20], [1, 0, 0, 0, 0, 1])
    // 创建名为Sphere对象的缩放关键帧,每个时间节点对应一组缩放
    let scaleTrack = new THREE.KeyframeTrack('Sphere.scale', [0, 10, 20], [1, 1, 1, 2, 2, 2, 1, 1, 1])
    // 默认的播放时间，一般取所有帧动画的最大时间
    let duration = 20
    // 多个帧动画作为元素创建一个剪辑clip对象，命名"default"，持续时间20
    let clip = new THREE.AnimationClip("default", duration, [posTrack, colorKF, scaleTrack])
    // 创建group对象的混合器,可以播放group中所有子对象的帧动画
    let mixer = new THREE.AnimationMixer(group)
    // 混合器通过clipAction方法创建剪辑clip的AnimationAction对象
    let animationAction = mixer.clipAction(clip)
    // 调节播放速度,默认1
    animationAction.timeScale = 20
    // 不循环播放
    animationAction.loop = THREE.LoopOnce
    animationAction.clampWhenFinished = true 
    animationAction.time = 5
    clip.duration = 10
    // 开始播放
    animationAction.play()
    
    /*
    // let mixer = null;
    let AnimationAction
    new THREE.ObjectLoader().load("/model/box.json", function(obj) {
    // new THREE.ObjectLoader().load("/model/lightmap.json", function(obj) {
      obj.scale.set(15, 15, 15);//缩放加载的模型
      // scene.add(obj);
      // obj作为混合器的参数，可以播放obj包含的帧动画数据
      // mixer = new THREE.AnimationMixer(obj);
      // obj.animations[0]：获得剪辑clip对象
      // // 剪辑clip作为参数，通过混合器clipAction方法返回一个操作对象AnimationAction
      AnimationAction = mixer.clipAction(obj.animations[0]);
      AnimationAction.play();
    })
    */
    let axisHelper = new THREE.AxesHelper(250);
    scene.add(axisHelper);
    /**
     * 光源设置
     */
    //点光源
    let point = new THREE.PointLight(0xffffff);
    point.position.set(400, 200, 300); //点光源位置
    scene.add(point); //点光源添加到场景中
    //环境光
    let ambient = new THREE.AmbientLight(0x888888);
    scene.add(ambient);
    // console.log(scene)
    // console.log(scene.children)
    /**
     * 相机设置
     */
    let width = window.innerWidth; //窗口宽度
    let height = window.innerHeight; //窗口高度
    let k = width / height; //窗口宽高比
    let s = 200; //三维场景显示范围控制系数，系数越大，显示的范围越大
    //创建相机对象
    let camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
    // camera = new THREE.PerspectiveCamera(60, k, 1, 1000)
    camera.position.set(0, 200, 600); //设置相机位置
    camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
    /**
     * 创建渲染器对象
     */
    let renderer = new THREE.WebGLRenderer();
    renderer.setSize(width, height);//设置渲染区域尺寸
    renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
    document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
    
    window.onresize = function() {
        let width = window.innerWidth; //窗口宽度
        let height = window.innerHeight; //窗口高度
        renderer.setSize(width, height);//设置渲染区域尺寸
        
        k = width / height; //窗口宽高比
        //修改相机对象属性
        camera.left = -s * k
        camera.right = s * k
        camera.top = s
        camera.bottom = -s
        camera.aspect = k
        camera.updateProjectionMatrix ()
    }
    
    Game = {
		tickLength: 16, 				// 20Hz
		lastTick: performance.now(),	// 最后更新时间
		stopKey: 0,
		canvas: null,
		context: null,
	}
	// 创建一个时钟对象Clock
	let clock = new THREE.Clock()
    function render(tFrame) {
        if (tFrame === undefined) {
            tFrame = performance.now()
            Game.lastTick = performance.now()
        }
        let nextTick = Game.lastTick + Game.tickLength
        let tickNum = 0
        if (tFrame > nextTick) {
            tickNum = Math.floor((tFrame - Game.lastTick) / Game.tickLength)
        }
        Game.lastTick = tFrame
        // clock.getDelta()方法获得两帧的时间间隔
        // 更新混合器相关的时间
        mixer.update(clock.getDelta())
        /*
        for (let num = 0; num < tickNum; ++num) {
            for (let i = 0, l = meshes.length; i < l; ++i) {
                meshes[i].position.set((i + 0.5 - l / 2) * 150, 0, 0)
                meshes[i].rotateY(3.14 / 180)
            }
        }
        */
        //执行渲染操作   指定场景、相机作为参数
        renderer.render(scene, camera);
        Game.stopKey = requestAnimationFrame(render)
    }
    function getV(distance) {
        let g = 0.5
        let t = Math.sqrt(distance * 2 / 9)
        return g * t
    }
    render()
    let controls = new THREE.OrbitControls(camera,renderer.domElement);//创建控件对象
    // controls.addEventListener('change', render);
    let slider = document.querySelector("input[name='slider']")
    document.onkeydown = function (e) {
      e = e || window.event;  //标准化事件对象
      let t = e.target || e.srcElement;  //获取发生事件的元素，兼容IE和DOM
      if (e.code == "Space") {  // 按下空格键 开始/暂停
        animationAction.paused = !animationAction.paused
      }
      if (e.code == "KeyD") {  // 前进
        if (animationAction.time < clip.duration) {
          animationAction.time += 0.01 * clip.duration
          slider.value = animationAction.time / clip.duration * 100
        }
      }
      if (e.code == "KeyA") {  // 后退
        if (animationAction.time > 0) {
          animationAction.time -= 0.01 * clip.duration
          slider.value = animationAction.time / clip.duration * 100
        }
      }
      console.log(e.code)
      console.log(animationAction.time)
    }
    slider.addEventListener('input', event => {
      console.log(event.target.value)
      animationAction.time = clip.duration * event.target.value * 0.01
    })
  </script>
</body>
</html>
